
// <copyright file="AbstractDbDataSource.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   This class is the abstraction of the core and common functionality of a DbDataSource.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Data.Common
{
    using System.Collections.Generic;
    using System.Data;

    using SubhadraSolutions.Sharp.Utils.Data.Helpers;

    /// <summary>
    /// This class is the abstraction of the core and common functionality of a DbDataSource.
    /// </summary>
    /// <typeparam name="T">
    /// </typeparam>
    public abstract class AbstractDbDataSource<T> : IDbDataSource<T>
    {
        #region Constructors and Finalizers

        /// <summary>
        ///     Initializes a new instance of the <see cref="AbstractDbDataSource{T}" /> class.
        /// </summary>
        protected AbstractDbDataSource()
        {
            this.ExecuteAsReader = false;
        }

        #endregion Constructors and Finalizers

        #region Properties

        /// <summary>
        ///     Gets or sets a value indicating whether [execute asynchronous reader].
        /// </summary>
        /// <value>
        ///     <c>true</c> if [execute asynchronous reader]; otherwise, <c>false</c>.
        /// </value>
        protected bool ExecuteAsReader { get; set; }

        /// <summary>
        ///     Gets the transaction context.
        /// </summary>
        /// <value>
        ///     The transaction context.
        /// </value>
        protected DbTransactionContext TransactionContext { get; private set; }

        #endregion Properties

        #region Public Methods and Operators

        /// <summary>
        /// Populates the specified dataTransferObjects.
        /// </summary>
        /// <param name="dataTransferObjects">
        /// The dataTransferObjects.
        /// </param>
        /// <param name="tag">
        /// The tag.
        /// </param>
        public virtual void Populate(IEnumerable<T> dataTransferObjects, object tag = null)
        {
            DatabaseHelper.Execute(dataTransferObjects, this.ExecuteAsReader, this.initializeCommand, this.BeforeExecute, this.AfterExecute, this.TransactionContext, tag);
        }

        /// <summary>
        /// Sets the database transaction context.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        public void SetDbTransactionContext(DbTransactionContext context)
        {
            this.TransactionContext = context;
        }

        #endregion Public Methods and Operators

        #region Methods

        /// <summary>
        /// After execute.
        /// </summary>
        /// <param name="command">
        /// The command.
        /// </param>
        /// <param name="dataTransferObject">
        /// The dataTransferObject.
        /// </param>
        /// <param name="returnedValue">
        /// The returned value.
        /// </param>
        /// <param name="tag">
        /// The tag.
        /// </param>
        protected abstract void AfterExecute(IDbCommand command, T dataTransferObject, object returnedValue, object tag);

        /// <summary>
        /// Before execute.
        /// </summary>
        /// <param name="command">
        /// The command.
        /// </param>
        /// <param name="dataTransferObject">
        /// The dataTransferObject.
        /// </param>
        /// <param name="tag">
        /// The tag.
        /// </param>
        protected abstract void BeforeExecute(IDbCommand command, T dataTransferObject, object tag);

        /// <summary>
        /// Initializes the command.
        /// </summary>
        /// <param name="command">
        /// The command.
        /// </param>
        /// <param name="tag">
        /// The tag.
        /// </param>
        protected abstract void initializeCommand(IDbCommand command, object tag);

        #endregion Methods
    }
}